template<typename FO>
struct binder2_3
{
    typedef typename FO::result_type result_type;
    typedef typename FO::first_argument first_argument;
    binder2_3(const FO& fo,
              typename FO::second_argument& a2,
              typename FO::third_argument& a3)
        :fo_(fo), a2_(a2), a3_(a3){}
    result_type operator()(first_argument a1){
        return fo_(a1, a2_, a3_);
    }
private:
    FO fo_;
    const typename FO::second_argument a2_;
    const typename FO::third_argument a3_;
};
template<typename FO, typename P2, typename P3> inline
binder2_3<FO> binder3(const FO& fo, const P2& a2, const P3& a3){
    return binder2_3<FO>(fo, a2, a3);
}


    
template<typename T>
struct in_range
{
    bool operator()(T const& value, T const &a, const T& b){
        return (value < b) and not (value < a);
    }
};

int main()
{
    binder3(in_range(), 400, 600)(200);
}
